package com.huilian.iotbox.client.service.impl;

import com.huilian.iotbox.client.dao.MemberStoreBalanceDao;
import com.huilian.iotbox.client.service.DeviceService;
import com.huilian.iotbox.client.service.MemberStoreBalanceService;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.MemberStoreBalanceDto;
import com.huilian.iotbox.data.po.MemberStoreBalance;
import com.huilian.iotbox.data.po.Order;
import com.huilian.iotbox.data.po.SystemConfig;
import com.huilian.iotbox.data.service.MemberStoreBalanceCommonService;
import com.huilian.iotbox.data.service.SystemConfigService;
import com.huilian.iotbox.data.utils.MD5SignUtil;
import com.huilian.iotbox.data.vo.DeviceVo;
import com.huilian.iotbox.data.vo.MemberStoreBalanceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.NoSuchAlgorithmException;
import java.util.*;

@Slf4j
@Service
public class MemberStoreBalanceServiceImpl implements MemberStoreBalanceService {

    // 增加或减少游戏币重试次数
    private static int count = 10;

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Resource
    private MemberStoreBalanceDao memberStoreBalanceDao;
    @Autowired
    private MemberStoreBalanceCommonService memberStoreBalanceCommonService;

    @Override
    public int insert(MemberStoreBalanceVo memberStoreBalanceVo) {
        return memberStoreBalanceDao.insert(memberStoreBalanceVo);
    }

    @Override
    public MemberStoreBalanceVo findMemberStoreBalanceByDeviceNoAndMemberId(MemberStoreBalanceDto memberStoreBalanceDto) {
        return memberStoreBalanceDao.findMemberStoreBalanceByDeviceNoAndMemberId(memberStoreBalanceDto);
    }


    /**
     * 会员等级晋升，记录总消费额
     *
     * @param order
     */
    @Override
    public void updateOrderRecord(Order order) {
        MemberStoreBalanceDto memberStoreBalanceDto = new MemberStoreBalanceDto();
        memberStoreBalanceDto.setMemberId(order.getMemberId());
        memberStoreBalanceDto.setMerchantStoreId(order.getMerchantStoreId());
        final MemberStoreBalanceVo balanceByMerchantStoreId = memberStoreBalanceDao.findMemberStoreBalanceByMerchantStoreId(memberStoreBalanceDto);
        balanceByMerchantStoreId.setTotalPay(balanceByMerchantStoreId.getTotalPay().add(order.getTotalAmount()));
        balanceByMerchantStoreId.setLatelyPay(order.getGmtPayment());
        if (balanceByMerchantStoreId.getTotalPay().compareTo(new BigDecimal("20000")) > 0) {
            balanceByMerchantStoreId.setLevelPay(3);
        } else if (balanceByMerchantStoreId.getTotalPay().compareTo(new BigDecimal("5000")) > 0) {
            balanceByMerchantStoreId.setLevelPay(2);
        }
        memberStoreBalanceDao.updateOrderRecord(balanceByMerchantStoreId);
    }

    /**
     * 扣除会员余额（乐观锁） <br/>
     * 需要参数： <br/>
     * memberId <br/>
     * merchantStoreId <br/>
     * userId <br/>
     * 和对应需要扣除的数额即可
     *
     * @param runCount
     * @param memberStoreBalanceDto
     * @return
     */
    @Override
    public MemberStoreBalanceDto minusBalance(int runCount, MemberStoreBalanceDto memberStoreBalanceDto) {
        long begin = System.currentTimeMillis();
        log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额线程" + Thread.currentThread().getName() + "第" + runCount + "次执行");
        log.info("参数为：" + memberStoreBalanceDto);
        memberStoreBalanceDto.setError(false);

        MemberStoreBalanceVo memberStoreBalanceVo = memberStoreBalanceDao.findByMemberIdAndMerchantStoreId(memberStoreBalanceDto);
        if (ObjectUtils.isEmpty(memberStoreBalanceVo)) {
            log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为空");
            memberStoreBalanceDto.setError(true);
            memberStoreBalanceDto.setErrorMsg("会员余额不足");
            return memberStoreBalanceDto;
        }
        memberStoreBalanceDto.setId(memberStoreBalanceVo.getId());
        memberStoreBalanceDto.setMoneyRechargeBalance(memberStoreBalanceVo.getMoneyRechargeBalance());
        memberStoreBalanceDto.setMoneyDonateBalance(memberStoreBalanceVo.getMoneyDonateBalance());
        memberStoreBalanceDto.setRechargeBalance(memberStoreBalanceVo.getRechargeBalance());
        memberStoreBalanceDto.setDonateBalance(memberStoreBalanceVo.getDonateBalance());
        memberStoreBalanceDto.setLottery(memberStoreBalanceVo.getLottery());
        memberStoreBalanceDto.setIntegral(memberStoreBalanceVo.getIntegral());

        MemberStoreBalance updateMemberStoreBalance = new MemberStoreBalance();
        updateMemberStoreBalance.setId(memberStoreBalanceDto.getId());
        updateMemberStoreBalance.setMemberId(memberStoreBalanceDto.getMemberId());
        updateMemberStoreBalance.setUserId(memberStoreBalanceDto.getUserId());
        updateMemberStoreBalance.setMerchantStoreId(memberStoreBalanceDto.getMerchantStoreId());

        //人民币
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getMinusMoney())) {
            if (memberStoreBalanceDto.getMinusMoney().compareTo(memberStoreBalanceVo.getMoneyRechargeBalance().add(memberStoreBalanceVo.getMoneyDonateBalance())) > 0) {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceVo.getId());
                memberStoreBalanceDto.setError(true);
                memberStoreBalanceDto.setErrorMsg("人民币余额不足");
                return memberStoreBalanceDto;
            } else {
                BigDecimal moneyBalance;
                //先扣除赠送人民币
                moneyBalance = memberStoreBalanceVo.getMoneyDonateBalance().subtract(memberStoreBalanceDto.getMinusMoney());
                if (moneyBalance.compareTo(BigDecimal.ZERO) > 0) {
                    updateMemberStoreBalance.setMoneyDonateBalance(moneyBalance);
                    memberStoreBalanceDto.setMoneyDonateBalance(moneyBalance);

                    memberStoreBalanceDto.setMinusMoneyRechargeBalance(BigDecimal.ZERO);
                    memberStoreBalanceDto.setMinusMoneyDonateBalance(memberStoreBalanceDto.getMinusMoney());
                } else {
                    updateMemberStoreBalance.setMoneyDonateBalance(BigDecimal.ZERO);
                    memberStoreBalanceDto.setMoneyDonateBalance(BigDecimal.ZERO);
                    memberStoreBalanceDto.setMinusMoneyRechargeBalance(moneyBalance.abs());

                    moneyBalance = memberStoreBalanceVo.getMoneyRechargeBalance().add(moneyBalance);
                    updateMemberStoreBalance.setMoneyRechargeBalance(moneyBalance);
                    memberStoreBalanceDto.setMoneyRechargeBalance(moneyBalance);

                    memberStoreBalanceDto.setMinusMoneyDonateBalance(memberStoreBalanceVo.getMoneyDonateBalance());
                }
            }
        }

        //游戏币
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getMinusCoins())) {
            if (memberStoreBalanceDto.getMinusCoins() > (memberStoreBalanceVo.getRechargeBalance() + memberStoreBalanceVo.getDonateBalance())) {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceVo.getId());
                memberStoreBalanceDto.setError(true);
                memberStoreBalanceDto.setErrorMsg("游戏币余额不足");
                return memberStoreBalanceDto;
            } else {
                int coinBalance;
                //先扣除赠送币
                coinBalance = memberStoreBalanceVo.getDonateBalance() - memberStoreBalanceDto.getMinusCoins();
                if (coinBalance >= 0) {
                    updateMemberStoreBalance.setDonateBalance(coinBalance);
                    memberStoreBalanceDto.setDonateBalance(coinBalance);

                    memberStoreBalanceDto.setMinusRechargeBalance(0);
                    memberStoreBalanceDto.setMinusDonateBalance(memberStoreBalanceDto.getMinusCoins());
                } else {
                    updateMemberStoreBalance.setDonateBalance(0);
                    memberStoreBalanceDto.setDonateBalance(0);
                    memberStoreBalanceDto.setMinusRechargeBalance(Math.abs(coinBalance));

                    coinBalance = memberStoreBalanceVo.getRechargeBalance() + coinBalance;
                    updateMemberStoreBalance.setRechargeBalance(coinBalance);
                    memberStoreBalanceDto.setRechargeBalance(coinBalance);

                    memberStoreBalanceDto.setMinusDonateBalance(memberStoreBalanceVo.getDonateBalance());
                }
            }
        }

        //彩票
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getMinusLottery())) {
            if (memberStoreBalanceDto.getMinusLottery() > memberStoreBalanceVo.getLottery()) {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceVo.getId());
                memberStoreBalanceDto.setError(true);
                memberStoreBalanceDto.setErrorMsg("彩票余额不足");
                return memberStoreBalanceDto;
            } else {
                updateMemberStoreBalance.setLottery(memberStoreBalanceVo.getLottery() - memberStoreBalanceDto.getMinusLottery());
                memberStoreBalanceDto.setLottery(memberStoreBalanceVo.getLottery() - memberStoreBalanceDto.getMinusLottery());
            }
        }

        //积分余额
        if (!ObjectUtils.isEmpty(memberStoreBalanceDto.getMinusIntegral())) {
            if (memberStoreBalanceDto.getMinusIntegral() > memberStoreBalanceVo.getIntegral()) {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceVo.getId());
                memberStoreBalanceDto.setError(true);
                memberStoreBalanceDto.setErrorMsg("积分余额不足");
                return memberStoreBalanceDto;
            } else {
                updateMemberStoreBalance.setIntegral(memberStoreBalanceVo.getIntegral() - memberStoreBalanceDto.getMinusIntegral());
                memberStoreBalanceDto.setIntegral(memberStoreBalanceVo.getIntegral() - memberStoreBalanceDto.getMinusIntegral());
            }
        }
        updateMemberStoreBalance.setLatelyPay(new Date());
        updateMemberStoreBalance.setVersionId(memberStoreBalanceVo.getVersionId());

        int i = memberStoreBalanceDao.updateBalance(updateMemberStoreBalance);
        if (i > 0) {
            log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额业务耗时：" + (System.currentTimeMillis() - begin) + "ms");
            return memberStoreBalanceDto;
        } else {
            if (count >= runCount) {
                return this.minusBalance(++runCount, memberStoreBalanceDto);
            } else {
                log.info("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceDto.getId());
                memberStoreBalanceDto.setError(true);
                memberStoreBalanceDto.setErrorMsg("为memberId:" + memberStoreBalanceDto.getMemberId() + "在场地:" + memberStoreBalanceDto.getMerchantStoreId() + "减少余额失败！memberStoreBalanceId为" + memberStoreBalanceDto.getId());
                return memberStoreBalanceDto;
            }
        }
    }

}
